/**
 * 
 */
package one.chchy.demo.sprintsecurity.authentication;

import java.io.IOException;
import java.security.Principal;

import com.fasterxml.jackson.databind.ObjectMapper;
import one.chchy.demo.sprintsecurity.ServerResponse;
import one.chchy.demo.sprintsecurity.util.EncryptionUtil;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 浏览器环境下登录成功的处理器
 * 
 * @author zhailiang
 */
@Component("imoocAuthenticationSuccessHandler")
public class ImoocAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private ObjectMapper objectMapper;

	@Autowired
	private SecurityProperties securityProperties;

	@Autowired
	private ClientDetailsService clientDetailsService;

	@Autowired
	private AuthorizationServerTokenServices authorizationServerTokenServices;

	@Autowired
	private PasswordEncoder passwordEncoder;

	private RequestCache requestCache = new HttpSessionRequestCache();

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.web.authentication.
	 * AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.
	 * HttpServletRequest, javax.servlet.http.HttpServletResponse,
	 * org.springframework.security.core.Authentication)
	 */
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
										Authentication authentication) throws IOException, ServletException {

		logger.info("登录成功");

//		super.onAuthenticationSuccess(request, response, authentication);
		String authentionHeader = request.getHeader("Authorization");

		if (authentionHeader == null || !authentionHeader.startsWith("Basic")){
			throw new UnapprovedClientAuthenticationException("请求头中无client信息");
		}

		String[] clientInfo = EncryptionUtil.decodeHeader(authentionHeader);

		if (clientInfo .length != 2){
			throw new UnapprovedClientAuthenticationException("请求头client信息出错");
		}

		String clientId = clientInfo[0];
		String clientSecret = clientInfo[1];

		ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

		if (clientDetails == null){
			throw new UnapprovedClientAuthenticationException("无法找到匹配的clientId信息 " + clientId);
		}

		if (!clientDetails.getClientSecret().equals(passwordEncoder.encode(clientSecret))){
			throw new UnapprovedClientAuthenticationException("clientSecret不匹配: " + clientId);
		}

		TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom");
		OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
		OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
		OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

		response.setContentType("application/json;charset=UTF-8");
		response.getWriter().write(objectMapper.writeValueAsString(ServerResponse.createBySuccess("登录成功", token)));
//
//		final String ipAddress = GeneralUtil.getClientIp(request);
//		final String userName = ((Principal) SecurityContextHolder.getContext().getAuthentication()).getName();
//		threadPoolTaskExecutor.execute(() -> idbService.ifPresent(dbService -> dbService.insertLoginLogs(userName, "login",
//				ipAddress)));
	}

}
